package com.yycx.module.bbs.provider.service.impl;

import com.yycx.common.base.entity.EntityMap;
import com.yycx.common.base.utils.FlymeUtils;
import com.yycx.common.constants.CommonConstants;
import com.yycx.common.mybatis.base.service.impl.BaseServiceImpl;
import com.yycx.common.mybatis.model.ResultBody;
import com.yycx.common.mybatis.query.CriteriaDelete;
import com.yycx.common.mybatis.query.CriteriaQuery;
import com.yycx.common.mybatis.query.CriteriaSave;
import com.yycx.common.mybatis.query.CriteriaUpdate;
import com.yycx.common.security.OpenHelper;
import com.yycx.common.utils.ApiAssert;
import com.yycx.common.utils.DateUtils;
import com.yycx.module.bbs.client.entity.BbsComment;
import com.yycx.module.bbs.client.entity.BbsContent;
import com.yycx.module.bbs.provider.mapper.BbsCommentMapper;
import com.yycx.module.bbs.provider.service.BbsCommentService;
import com.yycx.module.bbs.provider.service.BbsContentService;
import io.swagger.models.auth.In;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 帖子回复接口实现类
 *
 * @author flyme
 * @date 2019-12-06
 */
@Service
@Transactional(rollbackFor = Exception.class)
@AllArgsConstructor
public class BbsCommentServiceImpl extends BaseServiceImpl<BbsCommentMapper, BbsComment> implements BbsCommentService {

    private final BbsContentService contentService;


    @Override
    public ResultBody beforePageList(CriteriaQuery<BbsComment> cq, BbsComment comment, EntityMap requestMap) {
        ApiAssert.isNotEmpty("contentId不能为空", comment);
        Long contentId = comment.getContentId();
        initCriteriaQuery(cq, contentId);
        return ResultBody.ok();
    }


    @Override
    public List<EntityMap> listByContentIdAndSize(Long contentId, Integer showType, Integer size) {
        ApiAssert.isNotEmpty("contentId不能为空", contentId);
        CriteriaQuery cq = new CriteriaQuery(BbsComment.class);
        initCriteriaQuery(cq, contentId);
        List<EntityMap> resultList = selectEntityMap(cq);
        if (showType.equals(CommonConstants.INT_2)) {
            getChildComment(resultList, showType);
        }
        return resultList;
    }

    /**
     * 设置CriteriaQuery
     *
     * @param cq
     * @param contentId
     */
    private void initCriteriaQuery(CriteriaQuery cq, Long contentId) {
        Long userId = OpenHelper.getUserId();
        Integer showType = cq.getInt("showType", 2);
        cq.select(BbsComment.class, "commentId","contentId","dzNum", "replyContent", "replyImages", "createTime");
        cq.addSelect("replyUser.userId replyUserId", "replyUser.nickName replyNickName", "replyUser.userName replyUserName", "replyUser.userNo replyUserNo", "replyUser.avatar replyAvatar");
        if (showType.equals(CommonConstants.INT_1)) {
            //微信形式(张三回复李四),要查询给回复给谁
            cq.addSelect("toUser.userId toUserId", "toUser.nickName toNickName", "toUser.userName toUserName", "toUser.avatar toUserAvatar");
            cq.createJoin("com.yycx.module.user.client.entity.AppUser").setJoinAlias("toUser").setMainField("replyToUserId");
        } else {
            //微博形式只查询一级评论
            cq.isNull("comment.replyCommentId");
        }
        cq.addSelect("collecon_tag(2,'BbsComment',commentId," + userId + ") dzTag");
        cq.eq(BbsComment.class, "contentId", contentId);
        cq.eq(BbsComment.class, "replyState", CommonConstants.ENABLED);
        cq.createJoin("com.yycx.module.user.client.entity.AppUser").setJoinAlias("replyUser").setMainField("replyUserId");
    }


    @Override
    public ResultBody beforeAdd(CriteriaSave cs, BbsComment comment, EntityMap extra) {
        BbsContent content = contentService.getById(comment.getContentId());
        ApiAssert.isNotEmpty("帖子不存在", content);
        //评论ID
        Long replyCommentId = comment.getReplyCommentId();
        Long userId = OpenHelper.getUserId();
        comment.setDzNum(0);
        comment.setReplyState(CommonConstants.ENABLED);
        comment.setReplyUserId(userId);
        if (FlymeUtils.isEmpty(replyCommentId)) {
            comment.setReplyToUserId(content.getUserId());
        } else {
            BbsComment parent = getById(replyCommentId);
            comment.setReplyToUserId(parent.getReplyUserId());
        }
        return ResultBody.ok();
    }


    @Override
    public ResultBody afterAdd(CriteriaSave cs, BbsComment comment, EntityMap extra) {
        contentService.updateCommentNum(comment.getContentId(), 1);
        return ResultBody.msg("评论成功");
    }

    @Override
    public ResultBody afterDelete(CriteriaDelete cd, Serializable[] ids) {
        EntityMap params=cd.getRequestMap();
        Long contentId=params.getLong("contentId");
        if(FlymeUtils.isNotEmpty(contentId)) {
            contentService.updateCommentNum(contentId, -1);
        }
        return ResultBody.ok();
    }


    /**
     * 递归查询子评论
     *
     * @param parentComments
     * @return
     */
    @Override
    public List<EntityMap> getChildComment(List<EntityMap> parentComments, Integer showType) {
        if (FlymeUtils.isEmpty(parentComments)) {
            return null;
        }
        for (EntityMap parentComment : parentComments) {
            Long commentId = parentComment.getLong("commentId");
            Date createTime = parentComment.get("createTime");
            //格式化显示日期
            String showTime = DateUtils.formatFromTodayCn(createTime);
            parentComment.put("showTime", showTime);
            List<EntityMap> sonComments = selectByReplyCommentId(commentId, showType);
            List<EntityMap> child = getChildComment(sonComments, showType);
            child = FlymeUtils.isEmpty(child) ? new ArrayList<>() : child;
            parentComment.put("child", child);
        }
        return parentComments;
    }

    /**
     * 根据评论ID查询评论内容
     *
     * @param replyCommentId
     * @return
     */
    private List<EntityMap> selectByReplyCommentId(Long replyCommentId, Integer showType) {
        Long userId = OpenHelper.getUserId();
        CriteriaQuery cq = new CriteriaQuery(BbsComment.class);
        cq.select(BbsComment.class, "commentId", "contentId","replyContent","dzNum", "replyImages", "createTime");
        cq.addSelect("replyUser.userId replyUserId", "replyUser.nickName replyNickName", "replyUser.userName replyUserName", "replyUser.avatar replyAvatar");
        if (showType.equals(CommonConstants.INT_1)) {
            //微信形式(张三回复李四),要查询给回复给谁
            cq.addSelect("toUser.userId toUserId", "toUser.nickName toNickName", "toUser.userName toUserName", "toUser.avatar toUserAvatar");
            cq.createJoin("com.yycx.module.user.client.entity.AppUser").setJoinAlias("toUser").setMainField("replyToUserId");
        }
        cq.addSelect("collecon_tag(2,'BbsComment',commentId," + userId + ") dzTag");
        cq.eq(BbsComment.class, "replyCommentId", replyCommentId);
        cq.eq(BbsComment.class, "replyState", CommonConstants.ENABLED);
        cq.createJoin("com.yycx.module.user.client.entity.AppUser").setJoinAlias("replyUser").setMainField("replyUserId");
        cq.orderByDesc("comment.createTime");
        return selectEntityMap(cq);
    }

    /**
     * 统计回复数量
     *
     * @param contentId
     * @return
     */
    @Override
    public Long countByContentId(Long contentId) {
        CriteriaQuery cq = new CriteriaQuery(BbsComment.class);
        cq.eq(true, "contentId", contentId);
        cq.eq(true, "replyState", CommonConstants.ENABLED);
        return count(cq);
    }

    @Override
    public ResultBody getReplyPageList(Map params) {
        Long userId = OpenHelper.getUserId();
        CriteriaQuery<BbsComment> cq = new CriteriaQuery(params, BbsComment.class);
        cq.select(BbsComment.class, "commentId", "contentId", "replyCommentId", "replyContent","dzNum", "replyImages", "createTime");
        cq.addSelect("replyUser.userId replyUserId", "replyUser.nickName replyNickName", "replyUser.userName replyUserName", "replyUser.avatar replyAvatar");
        cq.eq("replyToUserId", userId);
        cq.createJoin("com.yycx.module.user.client.entity.AppUser").setJoinAlias("replyUser").setMainField("replyUserId");
        return basePageList(cq);
    }

    @Override
    public Boolean updateDzNum(Long commentId, Integer num) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.setSql(true, "dzNum=dzNum+" + num);
        cu.ge("dzNum", 0);
        cu.eq(true, "commentId", commentId);
        return update(cu);
    }

}
